package com.sinodata.bsm.center.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.springframework.stereotype.Repository;

import com.sinodata.bsm.center.bean.Condition;
import com.sinodata.bsm.center.bean.EventRuleBo;
import com.sinodata.bsm.center.bean.Page;
import com.sinodata.bsm.center.dao.BaseDao;
import com.sinodata.bsm.center.dao.EventRuleDao;
import com.sinodata.bsm.common.vo.DefaultEventRule;
import com.sinodata.bsm.common.vo.EventRule;

/**
 * <p>
 * Description: 事件规则查询接口
 * </p>
 *
 * @author dongyushi
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-25 PM 11:26:29    dongyushi        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
@Repository
public class EventRuleDaoImpl extends BaseDao implements EventRuleDao {
    @Override
    public Page<DefaultEventRule> findDefaultEventRuleByPage(Page<DefaultEventRule> page, Condition condition) {
        page.setTotal(getTotal(condition, page));
        StringBuilder sb = new StringBuilder("select der.id,");
        sb.append(" der.res_type_id,");
        sb.append(" der.event_type_id,");
        sb.append(" der.level_,");
        sb.append(" der.duration,");
        sb.append(" der.expr,");
        sb.append(" der.msg,");
        sb.append(" der.remarks,");
        sb.append(" der.vail_time,");
        sb.append(" der.status");
        sb.append(" from default_event_rule der");
        sb.append(" left outer join res_type rt on der.res_type_id = rt.id");
        sb.append(" left outer join event_type et on et.id = der.event_type_id");
        sb.append(" where 1 = 1 ");
        sb.append(getConditonSql(condition));
        sb.append(getOrderSql(page));
        Query query = getSession().createSQLQuery(sb.toString()).setFirstResult(page.getFirstResultNo()).setMaxResults(page.getPageSize());
        @SuppressWarnings("unchecked")
        List<Object[]> list = query.list();
        List<DefaultEventRule> result = new ArrayList<DefaultEventRule>();
        for (Object[] o : list) {
            DefaultEventRule defaultEventRule = new DefaultEventRule();
            defaultEventRule.setId(Long.valueOf(String.valueOf(o[0])));
            if (o[1] != null) {
                defaultEventRule.setResTypeId(Long.valueOf(String.valueOf(o[1])));
            }
            if (o[2] != null) {
                defaultEventRule.setEventTypeId(Long.valueOf(String.valueOf(o[2])));
            }
            if (o[3] != null) {
                defaultEventRule.setLevel(Integer.valueOf(String.valueOf(o[3])));
            }
            if (o[4] != null) {
                defaultEventRule.setDuration(Integer.valueOf(String.valueOf(o[4])));
            }
            if (o[5] != null) {
                defaultEventRule.setExpr(String.valueOf(o[5]));
            }
            if (o[6] != null) {
                defaultEventRule.setMsg(String.valueOf(o[6]));
            }
            if (o[7] != null) {
                defaultEventRule.setRemarks(String.valueOf(o[7]));
            }
            if (o[8] != null) {
                defaultEventRule.setVailTime(String.valueOf(o[8]));
            }
            if (o[9] != null) {
                defaultEventRule.setStatus(Integer.valueOf(String.valueOf(o[9])));
            }
            result.add(defaultEventRule);
        }
        page.setRows(result);
        return page;
    }

    private StringBuilder getConditonSql(Condition condition) {
        StringBuilder hql = new StringBuilder();
        Map<String, String> condMap = condition.getWhere();
        if (condMap.size() != 0) {
            hql.append(" and ( ");
            Iterator<String> keyItr = condMap.keySet().iterator();
            while (keyItr.hasNext()) {
                String key = keyItr.next();
                if (key.equals("eventTypeName")) {
                    hql.append("lower(et.name)").append(" like '%");
                    hql.append(condMap.get(key));
                    hql.append("%'");
                } else if (key.equals("resTypeName")) {
                    hql.append("lower(rt.name)").append(" like '%");
                    hql.append(condMap.get(key));
                    hql.append("%'");
                }
                hql.append(" and ");
            }
            hql.delete(hql.lastIndexOf(" and "), hql.length()).append(" ) ");
        }
        return hql;
    }

    private StringBuilder getOrderSql(Page<DefaultEventRule> page) {
        StringBuilder hql = new StringBuilder();
        Map<String, String> condMap = page.getOrder();
        if (condMap.size() != 0) {
            hql.append(" order by ");
            Iterator<String> keyItr = condMap.keySet().iterator();
            while (keyItr.hasNext()) {
                String key = keyItr.next();
                if (key.equals("levelName")) {
                    hql.append("der.level_").append(" ").append(condMap.get(key)).append(" , ");
                }
                if (key.equals("status")) {
                    hql.append("der.status").append(" ").append(condMap.get(key)).append(" , ");
                }
            }
            hql.delete(hql.lastIndexOf(" , "), hql.length());
        }
        return hql;
    }

    private int getTotal(Condition condition, Page<DefaultEventRule> page) {
        StringBuilder sb = new StringBuilder(" select count(*) from Default_Event_Rule der left outer join res_type rt on der.res_type_id = rt.id");
        sb.append(" left outer join event_type et on et.id = der.event_type_id where 1 = 1 ");
        sb.append(getConditonSql(condition));
        sb.append(getOrderSql(page));
        Query query = this.getSession().createSQLQuery(sb.toString());
        return ((BigDecimal) query.list().iterator().next()).intValue();
    }

    /*
     * (non-Javadoc)
     * @see com.sinodata.bsm.center.dao.EventRuleDao#findByRes(java.lang.Long)
     */
    @Override
    public List<EventRuleBo> findByRes(Long resId) {
        StringBuilder sb = new StringBuilder("select er.id,");
        sb.append(" er.res_id,");
        sb.append(" r.name as rname,");
        sb.append(" er.event_type_id,");
        sb.append(" et.name as etname,");
        sb.append(" er.level_,");
        sb.append(" er.duration,");
        sb.append(" er.expr,");
        sb.append(" er.msg,");
        sb.append(" er.remarks,");
        sb.append(" er.vail_time,");
        sb.append(" er.status");
        sb.append(" from event_rule er");
        sb.append(" left outer join res r on er.res_id = r.id");
        sb.append(" left outer join event_type et on et.id = er.event_type_id");
        sb.append(" where 1 = 1 ");
        sb.append(" and er.res_id =");
        sb.append(resId);
        Query query = getSession().createSQLQuery(sb.toString());
        @SuppressWarnings("unchecked")
        List<Object[]> list = query.list();
        List<EventRuleBo> result = new ArrayList<EventRuleBo>();
        for (Object[] o : list) {
            EventRule eventRule = new EventRule();
            EventRuleBo eventRuleBo = new EventRuleBo(eventRule);
            eventRule.setId(Long.valueOf(String.valueOf(o[0])));
            if (o[1] != null) {
                eventRule.setResId(Long.valueOf(String.valueOf(o[1])));
            }
            if (o[2] != null) {
                eventRuleBo.setResName(String.valueOf(o[2]));
            }
            if (o[3] != null) {
                eventRule.setEventTypeId(Long.valueOf(String.valueOf(o[3])));
            }
            if (o[4] != null) {
                eventRuleBo.setEventTypeName(String.valueOf(o[4]));
            }
            if (o[5] != null) {
                eventRule.setLevel(Integer.valueOf(String.valueOf(o[5])));
            }
            if (o[6] != null) {
                eventRule.setDuration(Integer.valueOf(String.valueOf(o[6])));
            }
            if (o[7] != null) {
                eventRule.setExpr(String.valueOf(o[7]));
            }
            if (o[8] != null) {
                eventRule.setMsg(String.valueOf(o[8]));
            }
            if (o[9] != null) {
                eventRule.setRemarks(String.valueOf(o[9]));
            }
            if (o[10] != null) {
                eventRule.setVailTime(String.valueOf(o[10]));
            }
            if (o[11] != null) {
                eventRule.setStatus(Integer.valueOf(String.valueOf(o[11])));
            }
            result.add(eventRuleBo);
        }
        return result;
    }

    @Override
    public void deleteByResId(Long resId) {
        String sql = "delete from event_rule where res_id='" + resId + "'";
        this.getSession().createSQLQuery(sql).executeUpdate();
    }

}